<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<title>Animating</title>
		<style type="text/css">
			html{
				height:100%;
				border:solid;
			}
			body{
				overflow:hidden;
				margin:0;
				padding:0;
			}
			div{
				width:50px;
				height:50px;
				background:blue;
				position:absolute;
				top:0;
				left:0;
				color:white;
				}			
		</style>
		<script type="text/javascript">
		
			function Animator(fps,timeout,formule){
				this.fps = fps||30;
				this.timeout = timeout||false;
				if(arguments.length > 2){
					arguments.slice = Array.prototype.slice;
					this.args = arguments.slice(2);
				}
				this.time = this.parse(this.fps);
			}
		
			/**
			 * "h" "m" "s" "ms"
			 */
			Animator.prototype = {
				constructor:Animator,
				IntervalID:-1,
				TimeoutID:-1,
				formule:function(){},
				fps:0,
				time:0,
				count:0,
				paused:true,
				parse_re:/^([\d.]+)([a-z]*)$/,
				
				onStart:function(){},
				onLoop:function(){},
				onFinish:function(){},
				
				run:function(){
					
					if(!this.paused){
						return false;
					}
				
					if(this.onStart.apply(this,this.args)==false){
						return false;
					}
					var a=this;

					this.IntervalID = window.setInterval(function(){
						a.count++;
						a.onLoop.apply(a,a.args);
					}, this.time);
					
					if(this.timeout){
						this.TimeoutID = window.setTimeout(function(){
							a.stop();
							window.clearTimeout(a.TimeoutID);
							a.TimeoutID=-1;
						})
					}
					this.paused=false;
				},
				stop:function(){
					this.paused=true;
					if(this.onFinish.apply(this,this.args)!=false){
						window.clearInterval(this.IntervalID);
					}
					this.IntervalID=-1;
				},
				parse:function(t){
					var n, m, v, d;
					v = t.toString().match(this.parse_re);
					d = parseFloat(v[0]);
					switch(v[2]){
						case 'h':n=d*60*60*1000;break;
						case 'm':n=d*60*1000;break;
						case 's':n=d*1000;break;
						case 'fps':n=d/1000
						case 'ms':
						default:n=d;break;
					}
					return n;
				},
				toString:function(){
					return "Animator [fps:"+this.fps+", time:"+(this.count*this.time)+"]";
				}
			}

			
		
			var a, x=0, y=0, tx=500, ty=500;
			window.onload=function(){
				a = new Animator(10,null,document.getElementById("box"));
				a.onStart=function(o){
					console.log("Start",o)
				}
				a.onLoop = function(o){
					//o.style.left = Effects.Formules.Bounce(o.offsetLeft, 500, 5.9, 1.3) + "px";
					//console.log(o.offsetLeft, o.offsetTop, tx, ty)
					
					o.style.left = (o.offsetLeft + (x = x * 0.9 + (tx - o.offsetLeft) * 0.9)) + "px";
				}
				a.onFinish=function(o){
					console.log("Finish",o)
				}
				

			}
			
			
			function Effects(target,config,formula){
				
			}
			
			Effects.Formules={
				Easing:function(current,target,delay){
					//v += ( vf - va ) / d
					return (current + (target - current) / delay);
				},
				Bounce:function(current,target,fricction,ratio){
					//v += (vt = vt * f + (vf - va) * r)

					var f=arguments.callee;
					return current + (f.z = ((f.z||0) * fricction + (current - target) * ratio));
				}
			}
						
			
			document.onclick=function(e){
				tx = e.screenX;
				ty = e.screenY;
				a.run();
			}
			
			
		</script>
	</head>
	<body>
		<div id="box"></div>
	</body>
</html>
